package com.inspur.iaic.service;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Locale;
import java.util.Random;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.inspur.iaic.config.NginxLogProperties;
import com.inspur.iaic.data.NginxLog;

/**
 * 日志采集器(非线程安全)
 *
 */
@Component
public class AccessLogCollectionService {
	private final Logger log = LoggerFactory.getLogger(getClass());
	Random random = new Random();
	@Autowired
	private NginxLogProperties nginxLogProperties;
	@Autowired
	private WarnAccessLogProcessor warnAccessLogProcessor;
	@Autowired
	private RealTimeAccessLogProcessor realTimeAccessLogProcessor;
	private SimpleDateFormat df1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	private SimpleDateFormat df2 = new SimpleDateFormat("dd/MMM/yyyy:HH:mm:ss", Locale.US);

	@Scheduled(fixedDelay = 1000)
	public void log() {
		NginxLog nl = new NginxLog();
		Date d = new Date();
		d.setTime(d.getTime() - (1000 * 60 * 5));
		String datetime = df2.format(d);
		// 使用|管道的命令，需要用"/bin/sh", "-c"的格式
		int number = getNumber(new String[] { "/bin/sh", "-c", "cat " + nginxLogProperties.getAccesslogPath() + "|grep \"" + datetime + "\"|wc -l" });//
		try {
			nl.setDatetime(df1.format(df2.parse(datetime)));
		} catch (ParseException e) {
			log.error("日期转换失败：" + datetime, e);
		}
		nl.setNumber(number);
		realTimeAccessLogProcessor.put(nl);
		if (number >= nginxLogProperties.getAccesslogWarnnumber()) {
			warnAccessLogProcessor.put(nl);
		}
	}

	private int getNumber(String... cmd) {
		Process process = null;
		try {
			process = Runtime.getRuntime().exec(cmd);
		} catch (Exception e) {
			log.error("执行命令出错：" + Arrays.toString(cmd), e);
			return 0;
		}

		try (InputStreamReader ir = new InputStreamReader(process.getInputStream()); InputStreamReader err = new InputStreamReader(process.getErrorStream());) {
			if (log.isDebugEnabled()) {
				log.debug("执行命令：" + Arrays.toString(cmd));
			}
			LineNumberReader input = new LineNumberReader(ir);
			String line;
			while ((line = input.readLine()) != null) {
				if (log.isInfoEnabled()) {
					log.info("执行命令：" + Arrays.toString(cmd) + "命令执行结果：" + line);
				}
				try {
					int number = Integer.parseInt(line);
					return number;
				} catch (Exception e) {
					log.error("统计数据失败：" + Arrays.toString(cmd) + ">>" + line, e);
				}
			}
			input = new LineNumberReader(err);
			while ((line = input.readLine()) != null) {
				log.error("执行命令出错：" + line);
			}
		} catch (Exception e) {
			log.error("命令结果收集失败：" + Arrays.toString(cmd), e);
		}
		return 0;
	}

}